/**
 * @date 2022/4/12
 * @description 常用工具函数
 * @author 
 */

import { setting } from '@/config/setting'
const { title } = setting
import { ElMessage, ElMessageBox } from 'element-plus'
import store from '@/store'
import router from '@/router'

import { nextTick } from 'vue'

//获取网页名称
export const getPageTitle = (pageTitle) => {
  if (pageTitle) {
    return `${pageTitle}-${title}`
  }
  return `${title}`
}

//获取接口成功以后弹出框
export const successHandle = (res) => {
  const { status, message } = res
  if (status === 200) {
    ElMessage({
      message: message,
      type: 'success',
    })
  }
}

//递归寻找菜单id，将所有id都push进一个数组中
export const recursiveId = (data) => {
  let arr = data.reduce((p, c) => {
    c.id && p.push(c.id)
    // 判断每一项中的children长度是否存在,并且也一个空数组,如果都满足,进行递归遍历push
    c.childresource && c.childresource.length && (p = p.concat(recursiveId(c.childresource)))
    return p
  }, [])

  return arr
}

//对象深拷贝
export const deepClone = (data) => {
  var type = getObjType(data)
  var obj
  if (type === 'array') {
    obj = []
  } else if (type === 'object') {
    obj = {}
  } else {
    // 不再具有下一层次
    return data
  }
  if (type === 'array') {
    for (var i = 0, len = data.length; i < len; i++) {
      obj.push(deepClone(data[i]))
    }
  } else if (type === 'object') {
    for (var key in data) {
      obj[key] = deepClone(data[key])
    }
  }
  return obj
}
export const getObjType = (obj) => {
  var toString = Object.prototype.toString
  var map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object',
  }
  return map[toString.call(obj)]
}

/**
 *列筛选----单个取消 单个选择
 *
 * @param {*} data 从父组件传来的数组
 * @param {*} e 状态：单个选中 单个取消
 * @param {*} currentItem 当前选中的项
 * @param {*} arr 要改变的数组
 *
 */
export const colFilters = (data, e, currentItem, arr) => {
  if (e) {
    //单个选中
    let checkData = data.filter((item) => {
      return currentItem === item.prop
    })
    checkData.map((val) => {
      arr.unshift(val)
    })
  } else {
    //单个取消
    let addItem = data.filter((item) => {
      return currentItem !== item.prop
    })
    arr = addItem
  }
  return arr
}

//递归添加层级深度标识
export const dfs = (list, level = 1) => {
  list.forEach((item) => {
    if (item.childresource) dfs(item.childresource, level + 1)
    item.level = level
  })
  return list
}

/**
 * 表格单项启用禁用弹出框确认操作
 * @param {Array} arr 调用的列表数组数据
 * @param {String} key 要操作的数据每列的key值
 * @param {Object} itemData 当前的item数据
 * @param {function} callback 回调函数
 * @param {Object} tip 提示文字
 */

export const tableIsEnable = (arr, key, itemData, callback) => {
  arr.forEach((item) => {
    if (item.id === itemData.id) {
      item[key] = !item[key]
    }
  })
  let tip = {
    key1: '',
    key2: '',
  }
  switch (key) {
    case 'valid':
      tip.key1 = '启用'
      tip.key2 = '禁用'
      break
    case 'isRecommend':
      tip.key1 = '开启推荐'
      tip.key2 = '关闭推荐'
      break
    case 'isHot':
      tip.key1 = '开启热门'
      tip.key2 = '关闭热门'
      break
  }
  if (key === 'del') {
    ElMessageBox.confirm(`您确定要删除此数据吗？`, '操作提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      dangerouslyUseHTMLString: true,
      type: 'warning',
    })
      .then(async () => {
        let newArr = []
        newArr.push(itemData.id)
        callback(newArr)
      })
      .catch(() => {})

    return false
  }
  ElMessageBox.confirm(`您确定要${!itemData[key] ? tip.key1 : tip.key2}吗？`, '操作提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    dangerouslyUseHTMLString: true,
    type: 'warning',
  })
    .then(async () => {
      let newArr = []
      newArr.push(itemData.id)
      callback(newArr)
    })
    .catch(() => {})
}

/**
 *批量操作弹窗
 * @param {Array} ids 表格中选中的数组
 * @param {String} type 状态
 * @param {Function} callback 回调函数
 */
export const batchHandle = (ids, type, callback) => {
  if (ids.length > 0) {
    let word = ''
    switch (type) {
      case 'START':
        word = '启用'
        break
      case 'STOP':
        word = '禁用'
        break
      case 'DEL':
        word = '删除'
        break
    }
    ElMessageBox.confirm(`您确定要批量${word}?`, '操作提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      dangerouslyUseHTMLString: true,
      type: 'warning',
    })
      .then(async () => {
        callback()
      })
      .catch(() => {})
  } else {
    ElMessage({
      message: '至少选择一项',
      type: 'warning',
    })
  }
}

export const lineHandle = (row, type, callback) => {
  let message = ''
  if (type === 'del') {
    message = '删除'
  } else if (type === 'valid') {
    row.valid = !row.valid
    message = row.valid ? '禁用' : '启用'
  } else if (type === 'isHot') {
    row.isHot = !row.isHot
    message = row.isHot ? '取消热门' : '设为热门'
  } else if (type === 'isRecommend') {
    row.isRecommend = !row.isRecommend
    message = row.isRecommend ? '取消推荐' : '设为推荐'
  }
  ElMessageBox.confirm(`您确定要将此数据${message}吗？`, '操作提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    dangerouslyUseHTMLString: true,
    type: 'warning',
  })
    .then(async () => {
      callback()
    })
    .catch(() => {})
}

/**
 * 文件下载
 * @param {Object} file 后端返回的file信息
 * @param {*} fileFlow 文件流
 */
export const fileDownload = (file, fileFlow) => {
  const name = file.name
  let type = ''
  switch (file.fileSuffix) {
    case 'docx':
      type = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8'
      break
    case 'doc':
      type = 'application/msword;charset=utf-8'
      break
    case 'pdf':
      type = 'application/pdf;charset=utf-8'
      break
    case 'xls':
      type = 'application/vnd.ms-excel;charset=utf-8'
      break
    case 'xlsx':
      type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
      break
  }
  let blob = new Blob([fileFlow], {
    type: type,
  })
  const url = window.URL.createObjectURL(blob)
  const aLink = document.createElement('a') //创建a标签
  aLink.style.display = 'none'
  aLink.href = url
  aLink.setAttribute('download', name) // 设置文件 name
  document.body.appendChild(aLink)
  aLink.click() //自执行下载
  document.body.removeChild(aLink) //下载完成移除元素
  window.URL.revokeObjectURL(url) //释放掉blob对象
}

/**
 *文件删除
 * @param {Object} file 当前的文件信息
 * @param {Array} fileList 所有的文件
 * @param {Number} type 1.新增 2.编辑
 * @param {Function} callback 回调函数，一般是调用后端删除接口
 * @param {Function} callback2 回调函数，用来把当前的fileList传递出去
 */

export const fileDel = (file, fileList, type, callback, callback2) => {
  fileList.push(file)
  ElMessageBox.confirm('是否删除该附件？删除不可恢复!', '操作提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(() => {
      if (type === 2) {
        //编辑---调用后端接口删除
        callback()
      } else {
        //新增---页面删除+数据删除
        fileList = fileList.filter((item) => item.uid !== file.uid)
        callback2(fileList)
      }
    })
    .catch(() => {})
}

/**
 * 删除当前路由，跳转想去的路由
 * @param {String} routeName 路由名字
 */

export const backRoute = (routeName, type) => {
  let view
  const visitedRouteList = store.getters['tabsBar/visitedRoutes']
  visitedRouteList.forEach((item) => {
    if (router.currentRoute.value.path == item.path) {
      view = item
    }
  })
  store.dispatch('tabsBar/delRoute', view)
  router.push({ name: routeName, params: { type: type } })
  store.dispatch('setting/setRouterView', false)
  nextTick(() => {
    store.dispatch('setting/setRouterView', true)
  })
}

/**
 *详情页面新增或者编辑成功弹出提示消息并删除当前路由以及刷新列表页
 * @param {Object} res 后端返回的数据信息
 * @param {String} routeName 路由名字
 */
export const detailHandleFinish = (res, routeName, type) => {
  successHandle(res)
  backRoute(routeName, type)
}
//递归遍历改名
export const renameObjectProperties  = (obj, oldName, newName) => {
  // 如果是数组，则使用forEach进行遍历，为了保持索引不变
  if (Array.isArray(obj)) {
    obj.forEach((item, index) => {
      // 如果item是对象或数组，则递归调用自身
      if (typeof item === 'object' && item !== null) {
        renameObjectProperties(item, oldName, newName);
      } else if (item === oldName) {
        // 如果item与旧属性名相同，则替换为新的属性名
        obj[index] = newName;
      }
    });
  } else if (typeof obj === 'object' && obj !== null) {
    // 如果是对象，则使用for...in遍历
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        if (key === oldName) {
          // 如果当前属性名与旧属性名相同，则替换为新的属性名
          obj[newName] = obj[oldName];
          delete obj[oldName];
        } else if (typeof obj[key] === 'object' && obj[key] !== null) {
          // 如果当前属性是对象，则递归调用自身
          renameObjectProperties(obj[key], oldName, newName);
        }
      }
    }
  }
  // 返回修改后的对象或数组
  return obj;
}
// 根据id 获取 name
export const findNameById = (arr, children, prop1 ,value, prop2) => {
  for (const item of arr) {
    if (item[prop1] === value) {
      return item[prop2];
    }
    if (item[children] && item[children].length > 0) {
      const result = findNameById(item[children], children, prop1 ,value, prop2);
      if (result) {
        return result;
      }
    }
  }
  return null; // 如果找不到对应id，则返回null
}